﻿using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Daybreak.Core
{
    public abstract class Streamer
    {
        internal static class TypeCache<T>
        {
            internal static Type Type = typeof(T);
        }

        protected bool _doRuntimeData = true;

        /// <summary>
        /// Field or Attribute mode
        /// </summary>
        protected bool _fieldMode = true;

        public Streamer()
        {
        }

        public virtual void BeginFieldSection()
        {
            _fieldMode = true;
        }

        public virtual void BeginAttributeSection()
        {
            _fieldMode = false;
        }

        #region primitive types

        public virtual void Visit(ref byte byteData, string filedName) { }
        public virtual void Visit(ref short shortData, string filedName) { }
        public virtual void Visit(ref int intData, string filedName) { }
        public virtual void Visit(ref float floatData, string filedName) { }
        public virtual void Visit(ref long longData, string filedName) { }
        public virtual void Visit(ref string txtData, string filedName) { }
        public virtual void Visit(ref bool boolData, string filedName) { }
        public virtual void Visit(ref DateTime timeData, string filedName) { }

        public virtual void VisitEnum<T>(ref T enumObject, string filedName) where T : struct, IConvertible { }

        #endregion

        #region XNA data types

        public virtual void Visit(ref Vector2 vecData, string filedName) { }

        public virtual void Visit(ref Vector3 vecData, string filedName) { }

        public virtual void Visit(ref Vector4 vecData, string filedName) { }

        public virtual void Visit(ref Quaternion quatData, string filedName) { }

        public virtual void Visit(ref Matrix matData, string filedName) { }

        public virtual void Visit(ref Color colorData, string filedName) { }


        #endregion

        #region primitive array types

        public virtual void VisitArray(ref byte[] dataArr, string filedName) { }

        public virtual void VisitArray(ref short[] dataArr, string filedName) { }

        public virtual void VisitArray(ref int[] dataArr, string filedName) { }

        public virtual void VisitArray(ref float[] dataArr, string filedName) { }

        public virtual void VisitArray(ref string[] dataArr, string filedName, string itemName) { }

        #endregion

        #region XNA array types

        public virtual void VisitArray(ref Vector2[] dataArr, string filedName) { }

        public virtual void VisitArray(ref Vector3[] dataArr, string filedName) { }

        public virtual void VisitArray(ref Vector4[] dataArr, string filedName) { }

        public virtual void VisitArray(ref Quaternion[] dataArr, string filedName) { }

        public virtual void VisitArray(ref Matrix[] dataArr, string filedName) { }

        public virtual void VisitArray(ref Color[] dataArr, string filedName) { }


        #endregion

        public virtual void VisitAssetArray<T>(ref List<T> array) where T : class, IAsset, new()
        {
            //int arrayLength = BeginArray<T>(filedName, ref array.Items);

            //for (int i = 0; i < array.Count; i++)
            //    VisitAsset<T>(ref array.Items[i]);

        }

        public virtual void VisitAssetArray<T>(ref T[] array) where T : IAsset, new()
        {
        }

        public virtual void Visit(ref IAsset asset) { }

        public virtual void VisitAsset<T>(ref T asset) where T : IAsset, new()
        {
        }

        protected virtual int BeginArray<T>(string filedName, ref T[] dataArr)
        {
            if (dataArr == null)
                return 0;

            return dataArr.Length;

        }

    }
}
